package com.smart.translator.util;

import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.Locale;
import android.os.Handler;
import android.os.Looper;

/**
 * eSpeak离线TTS引擎
 * 基于eSpeak的轻量级离线语音合成引擎
 * 当eSpeak不可用时，自动降级到系统TTS
 */
public class eSpeakTtsEngine {
    private static final String TAG = "eSpeakTtsEngine";
    
    private Context context;
    private AudioManager audioManager;
    private ExecutorService executor;
    private Handler mainHandler;
    private boolean isInitialized = false;
    private boolean isEspeakAvailable = false;
    private String espeakPath;
    private String voicePath;
    
    // 备用系统TTS
    private TextToSpeech fallbackTts;
    
    // 音频参数
    private static final int SAMPLE_RATE = 22050;
    private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_OUT_MONO;
    private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    private static final int BUFFER_SIZE = AudioTrack.getMinBufferSize(SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT);
    
    public interface TtsCallback {
        void onSuccess(String text);
        void onError(String text, String error);
        void onFallback(String text);
    }
    
    public eSpeakTtsEngine(Context context) {
        this.context = context;
        this.audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        this.executor = Executors.newSingleThreadExecutor();
        this.mainHandler = new Handler(Looper.getMainLooper());
        
        initEngine();
    }
    
    /**
     * 初始化eSpeak引擎
     */
    private void initEngine() {
        executor.execute(() -> {
            try {
                // 尝试初始化eSpeak
                if (initEspeakBinary()) {
                    isEspeakAvailable = true;
                    isInitialized = true;
                    Log.d(TAG, "eSpeak引擎初始化成功");
                } else {
                    // eSpeak不可用，初始化备用系统TTS
                    Log.w(TAG, "eSpeak不可用，初始化备用系统TTS");
                    initFallbackTts();
                }
                
            } catch (Exception e) {
                Log.e(TAG, "eSpeak引擎初始化失败", e);
                initFallbackTts();
            }
        });
    }
    
    /**
     * 初始化eSpeak二进制文件
     */
    private boolean initEspeakBinary() {
        try {
            // 检查assets中是否有eSpeak文件
            String[] espeakFiles = {"espeak/espeak", "espeak/voices", "espeak/phonindex"};
            for (String fileName : espeakFiles) {
                try {
                    context.getAssets().open(fileName).close();
                } catch (IOException e) {
                    Log.w(TAG, "eSpeak文件不存在: " + fileName);
                    return false;
                }
            }
            
            // 复制eSpeak文件到应用目录
            File binDir = new File(context.getFilesDir(), "bin");
            if (!binDir.exists()) {
                binDir.mkdirs();
            }
            
            espeakPath = new File(binDir, "espeak").getAbsolutePath();
            File espeakFile = new File(espeakPath);
            
            if (!espeakFile.exists()) {
                copyAssetFile("espeak/espeak", espeakFile);
                espeakFile.setExecutable(true);
            }
            
            // 复制语音数据文件
            File voiceDir = new File(context.getFilesDir(), "espeak-data");
            if (!voiceDir.exists()) {
                voiceDir.mkdirs();
            }
            
            voicePath = voiceDir.getAbsolutePath();
            
            String[] voiceFiles = {"voices", "phonindex", "phondata", "intonations"};
            for (String fileName : voiceFiles) {
                File voiceFile = new File(voiceDir, fileName);
                if (!voiceFile.exists()) {
                    copyAssetFile("espeak/" + fileName, voiceFile);
                }
            }
            
            Log.d(TAG, "eSpeak二进制文件初始化成功");
            return true;
            
        } catch (Exception e) {
            Log.e(TAG, "eSpeak二进制文件初始化失败", e);
            return false;
        }
    }
    
    /**
     * 复制assets文件
     */
    private void copyAssetFile(String assetPath, File targetFile) throws IOException {
        InputStream input = context.getAssets().open(assetPath);
        FileOutputStream output = new FileOutputStream(targetFile);
        byte[] buffer = new byte[1024];
        int length;
        while ((length = input.read(buffer)) > 0) {
            output.write(buffer, 0, length);
        }
        input.close();
        output.close();
        Log.d(TAG, "文件已复制: " + assetPath + " -> " + targetFile.getAbsolutePath());
    }
    
    /**
     * 初始化备用系统TTS
     */
    private void initFallbackTts() {
        try {
            fallbackTts = new TextToSpeech(context, status -> {
                if (status == TextToSpeech.SUCCESS) {
                    int result = fallbackTts.setLanguage(Locale.CHINESE);
                    if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                        fallbackTts.setLanguage(Locale.getDefault());
                    }
                    fallbackTts.setPitch(1.0f);
                    fallbackTts.setSpeechRate(1.0f);
                    isInitialized = true;
                    Log.d(TAG, "备用系统TTS初始化成功");
                } else {
                    Log.e(TAG, "备用系统TTS初始化失败: " + status);
                    isInitialized = false;
                }
            });
        } catch (Exception e) {
            Log.e(TAG, "备用系统TTS初始化异常", e);
            isInitialized = false;
        }
    }
    
    /**
     * 朗读文本
     */
    public void speak(String text, TtsCallback callback) {
        if (text == null || text.trim().isEmpty()) {
            if (callback != null) {
                callback.onError(text, "文本为空");
            }
            return;
        }
        
        if (!isInitialized) {
            Log.w(TAG, "TTS引擎未初始化");
            if (callback != null) {
                callback.onError(text, "TTS引擎未初始化");
            }
            return;
        }
        
        executor.execute(() -> {
            try {
                // 设置音频输出
                setupAudioOutput();
                
                if (isEspeakAvailable) {
                    // 使用eSpeak合成语音
                    byte[] audioData = synthesizeSpeech(text);
                    
                    if (audioData != null && audioData.length > 0) {
                        // 播放音频
                        playAudio(audioData);
                        
                        if (callback != null) {
                            mainHandler.post(() -> callback.onSuccess(text));
                        }
                        Log.d(TAG, "eSpeak朗读成功: " + text);
                    } else {
                        Log.w(TAG, "eSpeak合成失败，使用备用TTS");
                        useFallbackTts(text, callback);
                    }
                } else {
                    // 使用备用系统TTS
                    useFallbackTts(text, callback);
                }
                
            } catch (Exception e) {
                Log.e(TAG, "TTS朗读异常", e);
                if (callback != null) {
                    mainHandler.post(() -> callback.onError(text, e.getMessage()));
                }
            }
        });
    }
    
    /**
     * 使用eSpeak合成语音
     */
    private byte[] synthesizeSpeech(String text) {
        try {
            // 创建临时文件存储音频数据
            File tempFile = File.createTempFile("espeak_", ".wav", context.getCacheDir());
            
            // 构建eSpeak命令
            String[] command = {
                espeakPath,
                "-v", "zh",  // 中文语音
                "-s", "150", // 语速
                "-p", "50",  // 音调
                "-a", "100", // 音量
                "-w", tempFile.getAbsolutePath(), // 输出到WAV文件
                text
            };
            
            // 执行eSpeak命令
            ProcessBuilder pb = new ProcessBuilder(command);
            pb.environment().put("ESPEAK_DATA_PATH", voicePath);
            Process process = pb.start();
            
            // 等待进程完成
            int exitCode = process.waitFor();
            
            if (exitCode == 0 && tempFile.exists() && tempFile.length() > 0) {
                // 读取WAV文件并转换为PCM数据
                byte[] wavData = readFileToByteArray(tempFile);
                byte[] pcmData = convertWavToPcm(wavData);
                
                // 清理临时文件
                tempFile.delete();
                
                return pcmData;
            } else {
                Log.e(TAG, "eSpeak命令执行失败，退出码: " + exitCode);
                tempFile.delete();
                return null;
            }
            
        } catch (Exception e) {
            Log.e(TAG, "eSpeak语音合成失败", e);
            return null;
        }
    }
    
    /**
     * 使用备用系统TTS
     */
    private void useFallbackTts(String text, TtsCallback callback) {
        if (fallbackTts != null) {
            try {
                int result = fallbackTts.speak(text, TextToSpeech.QUEUE_FLUSH, null, "fallback_tts");
                if (result == TextToSpeech.SUCCESS) {
                    Log.d(TAG, "备用系统TTS朗读成功: " + text);
                    if (callback != null) {
                        mainHandler.post(() -> callback.onSuccess(text));
                    }
                } else {
                    Log.w(TAG, "备用系统TTS朗读失败，使用备用方案");
                    if (callback != null) {
                        mainHandler.post(() -> callback.onFallback(text));
                    }
                }
            } catch (Exception e) {
                Log.e(TAG, "备用系统TTS朗读异常", e);
                if (callback != null) {
                    mainHandler.post(() -> callback.onFallback(text));
                }
            }
        } else {
            Log.w(TAG, "备用系统TTS不可用，使用备用方案");
            if (callback != null) {
                mainHandler.post(() -> callback.onFallback(text));
            }
        }
    }
    
    /**
     * 读取文件到字节数组
     */
    private byte[] readFileToByteArray(File file) throws IOException {
        java.io.FileInputStream fis = new java.io.FileInputStream(file);
        byte[] data = new byte[(int) file.length()];
        fis.read(data);
        fis.close();
        return data;
    }
    
    /**
     * 将WAV文件转换为PCM数据
     */
    private byte[] convertWavToPcm(byte[] wavData) {
        // 简单的WAV到PCM转换
        // WAV文件头通常是44字节
        if (wavData.length <= 44) {
            return new byte[0];
        }
        
        // 跳过WAV文件头，提取PCM数据
        byte[] pcmData = new byte[wavData.length - 44];
        System.arraycopy(wavData, 44, pcmData, 0, pcmData.length);
        
        return pcmData;
    }
    
    /**
     * 播放音频数据
     */
    private void playAudio(byte[] audioData) {
        AudioTrack audioTrack = null;
        try {
            audioTrack = new AudioTrack.Builder()
                .setAudioAttributes(new android.media.AudioAttributes.Builder()
                    .setUsage(android.media.AudioAttributes.USAGE_MEDIA)
                    .setContentType(android.media.AudioAttributes.CONTENT_TYPE_SPEECH)
                    .build())
                .setAudioFormat(new android.media.AudioFormat.Builder()
                    .setEncoding(AUDIO_FORMAT)
                    .setSampleRate(SAMPLE_RATE)
                    .setChannelMask(CHANNEL_CONFIG)
                    .build())
                .setBufferSizeInBytes(BUFFER_SIZE)
                .setTransferMode(AudioTrack.MODE_STREAM)
                .build();
            
            audioTrack.play();
            audioTrack.write(audioData, 0, audioData.length);
            
            // 等待播放完成
            audioTrack.stop();
            
        } catch (Exception e) {
            Log.e(TAG, "音频播放失败", e);
        } finally {
            if (audioTrack != null) {
                audioTrack.release();
            }
        }
    }
    
    /**
     * 设置音频输出
     */
    private void setupAudioOutput() {
        try {
            if (audioManager != null) {
                audioManager.setMode(AudioManager.MODE_NORMAL);
                audioManager.setSpeakerphoneOn(true);
                
                // 设置音量到最大
                int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
                audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume, 0);
                
                Log.d(TAG, "音频输出设置完成");
            }
        } catch (Exception e) {
            Log.e(TAG, "设置音频输出失败", e);
        }
    }
    
    /**
     * 停止朗读
     */
    public void stop() {
        if (fallbackTts != null) {
            fallbackTts.stop();
        }
    }
    
    /**
     * 释放资源
     */
    public void release() {
        if (fallbackTts != null) {
            fallbackTts.stop();
            fallbackTts.shutdown();
            fallbackTts = null;
        }
        
        if (executor != null) {
            executor.shutdown();
        }
        
        isInitialized = false;
        isEspeakAvailable = false;
        Log.d(TAG, "eSpeakTtsEngine已释放");
    }
    
    /**
     * 检查是否已初始化
     */
    public boolean isInitialized() {
        return isInitialized;
    }
    
    /**
     * 检查eSpeak是否可用
     */
    public boolean isEspeakAvailable() {
        return isEspeakAvailable;
    }
} 